{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Contributing Guide\n",
    "\n",
    "Welcome! So, you're interested in making your first open source contribution to STUMPY? We're excited to start this journey with you. Here are some things that will help you get started."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Git and GitHub\n",
    "\n",
    "You don't need a [GitHub](https://github.com/) account to use STUMPY but you do need an account if you want to make a code or documentation contribution. This GitHub account will allow you to contribute to many of the most popular open source projects. Additionally, it will give you a place to store, track, and coordinate progress on your own projects. GitHub is a `remote repository` for the version control system `git`. `Git` is a versioning tool that tracks changes in projects by constructing a directed acyclic graph (fancy way of allowing us to create `branches`, `revert` changes, and identify `conflicts`). You can use `git` on your local machine but when you want to save your work or collaborate with other team members, you `push` your work to a `remote` repository. In this case, that `remote` will be GitHub.\n",
    "\n",
    "With all of that in mind, you'll also need to [install git](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git).\n",
    "\n",
    "> Warning: Don't confuse git and GitHub. Git is a tool used for version control. GitHub is an online platform used as a remote repository for git projects.\n",
    "\n",
    "Checklist:  \n",
    "- [ ] Create GitHub account  \n",
    "- [ ] Install Git"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2020-09-24T12:31:30.189188Z",
     "iopub.status.busy": "2020-09-24T12:31:30.189188Z",
     "iopub.status.idle": "2020-09-24T12:31:30.195188Z",
     "shell.execute_reply": "2020-09-24T12:31:30.195188Z",
     "shell.execute_reply.started": "2020-09-24T12:31:30.189188Z"
    }
   },
   "source": [
    "## Find your contribution\n",
    "\n",
    "You've decided that you want to contribute but how do you approach a new project and figure out where you can help? This will feel like like trying to jump into a conversation that's been happening for months (or years) and can often be intimidating. If you've used the project before, you'll be more familiar with its structure and API but you probably haven't \"peeked behind the curtain\". The best place to get started is the list of [Issues](https://github.com/stumpy-dev/stumpy/issues). These are feature requests/changes/bugs that other people have identified. Feel free to peruse the list to get a feel for all of the ongoing work in the project. Often, maintainers will have a labeling system to organize the issues. These labels may include things like `documentation` or `enhancement`. For new contributors, many projects have a [good first issue label](https://github.com/stumpy-dev/stumpy/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22).\n",
    "\n",
    "Your next stop, should always be [CONTRIBUTING.md](https://github.com/stumpy-dev/stumpy/blob/master/CONTRIBUTING.md). Here, the maintainers outline any guidance they have for contributors,\n",
    "\n",
    "If you click on any issue, you'll see a running history of discussions. This serves as the record of thoughts around that specific issue. For some issues, you may see an ongoing conversation. In others, you may just see the initial issue. This is your chance to have a dialogue with the maintainers. If you've found an open issue that interests you and you think you may be able to solve it, feel free to leave a message. Remember that maintainers are people too and at STUMPY, they're excited to help new contributors. Here's an example of a potential message:\n",
    "\n",
    "> First time contributor here! I see that this issue is related to a bug caused by an incorrect variable name. Does that seem right to you? If so, I'd like to take this issue and submit a pull request to fix it.\n",
    "\n",
    "This message does a couple of things. It shows that you've done a little bit of research into the issue (demonstrates respect for the maintainers' time), gets their input (helps you solve the problem), and makes sure they will accept a pull request (saves your time/effort). Remember how you're jumping into an ongoing conversation? Sometimes an issue will become irrelevant or obsolete based on changes happening elsewhere in the package. A quick note like this lets the maintainer know that you're going to work on this issue and confirms that it is still a valuable issue.\n",
    "\n",
    "> Warning: If you can tell someone else is actively working on an issue, don't take it.\n",
    "\n",
    "Checklist:  \n",
    "- [ ] Identify an issue  \n",
    "- [ ] Read CONTRIBUTING.md  \n",
    "- [ ] Post your proposal in the issue"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Setup your Branch\n",
    "\n",
    "Okay, so you've chosen an issue to work on and the maintainers are excited to have your help. Now, let's get to work!\n",
    "\n",
    "First, you need to create a copy of the repository for you to work off of; this is called a `fork`. Here are instructions on [forking a repository](https://docs.github.com/en/github/getting-started-with-github/fork-a-repo). Now you have your own copy associated with your GitHub account.\n",
    "\n",
    "Next, you need to `clone` this copy of the repository. This simply downloads it to your computer so that you can work on it. Here are instructions on [cloning a repository](https://docs.github.com/en/github/creating-cloning-and-archiving-repositories/cloning-a-repository). It's super important to *remember* to clone your fork and not [STUMPY](https://github.com/stumpy-dev/stumpy).\n",
    "\n",
    "Then, you'll need to create a `branch`. Here's an overview of [how git branches work](https://git-scm.com/book/en/v2/Git-Branching-Basic-Branching-and-Merging) but if you're working in the command line, then you probably need to type `git checkout -b branch_name`. In this case, `branch_name` should be replaced with something descriptive about the change that you are making like `change_incorrect_variable` or `document_x`.\n",
    "\n",
    "Now, any changes you make in the project will be reflected in your branch. Later, You'll want your changes to be `merged` into the main STUMPY repository (so that everyone can benefit from your contribution). Your branch reflects all of these changes.\n",
    "\n",
    "> Warning: Create your branch before making any changes.\n",
    "\n",
    "Checklist:  \n",
    "- [ ] Fork STUMPY to your own account  \n",
    "- [ ] Clone a local copy for your fork\n",
    "- [ ] Create a branch for your work"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Adhere to CONTRIBUTING.md Guidance\n",
    "\n",
    "One of the great benefits of open source is the ability to collaborate with developers from around the world. However, you can imagine that combining their contributions into one coherent codebase while maintaining consistency can be challenging. Luckily, recent gains in automated tooling have made this a lot easier. Remember [CONTRIBUTING.md](https://github.com/stumpy-dev/stumpy/blob/master/CONTRIBUTING.md)? There are a couple of things we want to make sure we do before we submit a `pull request`.\n",
    "\n",
    "First, if you implemented a new feature or changed an existing feature, then you are also responsible for providing the unit test. This can often be just as much work as the feature, so make sure you account for it.\n",
    "\n",
    "Next, run `flake8` and `black`. [flake8](https://flake8.pycqa.org/en/latest/) is a linter that checks the style and quality of the code. [black](https://pypi.org/project/black/) makes any necessary changes to ensure consistent code format.\n",
    "\n",
    "Checklist:  \n",
    "- [ ] Write/update any unit tests  \n",
    "- [ ] Run `black --exclude=\".*\\.ipynb\" --extend-exclude=\".venv\" --diff ./` to reformat any python files you changed  \n",
    "- [ ] Run `flake8 --extend-exclude=.venv ./` to identify any formatting errors before you submit your `pull request`  \n",
    "- [ ] Run the unit tests. In STUMPY, you'll run `./setup.sh dev && ./test.sh`"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Setting Up Your Environment\n",
    "\n",
    "When working on a new project, there are often going to be dependencies. In order to isolate dependencies between different projects, it's a good practice to use a virtual environment. STUMPY supports both [venv](https://docs.python.org/3/library/venv.html) and [conda](https://docs.conda.io/en/latest/). After creating and activating either of these virtual environments, any dependencies you install will be isolated (so they don't break anything else on your system).\n",
    "\n",
    "First, if you are using `venv` then you can install STUMPY and all of its the dependencies using the convenient `./setup.sh dev`. If you are building STUMPY within a `conda` environment, then you may consider using the `./conda.sh` shell script which will automatically assist you in installing all of the required dependencies required for STUMPY development. \n",
    "\n",
    "A good check to make sure everything is working 100% is to run the unit tests. For STUMPY, we have scripts to help you do that. You'll run `./setup.sh dev && ./test.sh`. In some cases, you may notice an uninstallation message for STUMPY but don't worry. This happens if you have had previously installed STUMPY as the `./setup.sh dev` command first uninstalls any existing version of STUMPY and then it will re-installs it from source (the local, cloned, development version). So, everything should be all set.\n",
    "\n",
    "Ideally, you'll see the excellent STUMPY test coverage passing. If things start failing or breaking, then you may have a missing dependency problem. There's nothing worse than finding this out *after* you've made changes.\n",
    "\n",
    "If all of the tests pass, then you know that you have a working copy of STUMPY to start your development on. Go ahead and implement your feature or change!\n",
    "\n",
    "Checklist:  \n",
    "- [ ] Create a virtual environment  \n",
    "- [ ] Install dependencies  \n",
    "- [ ] Run the unit tests"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Push your code to GitHub\n",
    "\n",
    "Now your `fork` contains updated code and unit tests that adhere to the STUMPY formatting standards. If you're comfortable with `git` or have been doing work between multiple workstations, you may have `pushed` your `commits` to GitHub already. If not, then now is the time!\n",
    "\n",
    "When you were working on your change, you probably saved your files all the time. Those changes were saved on your local machine, but never updated in version control. To do that, you'll need to `git add <files>` (\"hey git, please track these files\"), `git commit -m <message>` (\"hey git, at this point, I want to save\") and `git push` (\"Hey git, take the last commit and move it to GitHub\") as described [here](https://docs.github.com/en/github/managing-files-in-a-repository/adding-a-file-to-a-repository-using-the-command-line). Remember to [write a good commit message](https://chris.beams.io/posts/git-commit/).\n",
    "\n",
    "__NOTE:__ Try to keep your commits small and easily digestable. A good rule of thumb is to keep each commit to 50 lines of code or less (excluding docstrings).\n",
    "\n",
    "> Warning: If this is your first time using git, it may through a warning about global settings. Luckily, that warning tells you exactly how to fix it.\n",
    "\n",
    "Checklist:  \n",
    "- [ ] `git add your_file`  \n",
    "- [ ] `git commit -m 'Great Commit Message'`  \n",
    "- [ ] `git push`"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Sync your Fork with the Parent Repository\n",
    "\n",
    "While you are working on your development branch, it is likely that the STUMPY repository will have undergone new changes that your fork does not have. It is recommended, therefore, to sync your fork with its parent repository before submitting a pull request. For more information refer to the [Github documentation](https://docs.github.com/en/github/collaborating-with-pull-requests/working-with-forks/syncing-a-fork).\n",
    "\n",
    "Checklist (fetching upstream through Github):  \n",
    "- [ ] Sync your fork with the upstream/parent repository (see screenshot below)  \n",
    "- [ ] `git checkout main`  \n",
    "- [ ] `git pull`  \n",
    "- [ ] `git checkout branch_name`  \n",
    "- [ ] `git merge main`  \n",
    "- [ ] Run the unit tests: `./setup.sh dev && ./test.sh`  \n",
    "\n",
    "Checklist (fetching upstream locally):  \n",
    "- [ ] `git fetch upstream`\n",
    "- [ ] `git checkout main`  \n",
    "- [ ] `git merge upstream/main`  \n",
    "- [ ] `git checkout branch_name`  \n",
    "- [ ] `git merge main`  \n",
    "- [ ] Run the unit tests: `./setup.sh dev && ./test.sh`  \n",
    "\n",
    "![Fetch Upstream Fork](images/fetch_upstream_fork.png)  "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    ":::{admonition} Instructions for Pulling Main into a Development Branch\n",
    ":class: toggle\n",
    "1. Open a terminal\n",
    "2. Change the current working directory to your local development repository (e.g., cd Git/stumpy_dev.git)\n",
    "3. Check out your local development branch (e.g., git switch some_new_feature)\n",
    "4. Commit all changes in your local development branch (e.g., git add some_file.py and git commit)\n",
    "5. Fetch the branches and their respective commits from the upstream repository (e.g., git fetch upstream)\n",
    "6. Check out your fork's local default branch (e.g., git checkout main)\n",
    "7. Merge the changes from the upstream default branch - in this case, upstream/main - into your local default branch (e.g., git merge upstream/main). This brings your fork's default branch into sync with the upstream repository, without losing your local changes.\n",
    "8. If your local main branch didn't have any unique commits, Git will perform a fast-forward. Otherwise, if your local main branch had unique commits, you may need to resolve conflicts. Note that this does not affect your development branch!\n",
    "9. Next, switch over to your development branch (e.g., git switch some_new_feature)\n",
    "10. Finally, merge the main branch into your development branch (e.g., git merge main)\n",
    "    - You may see something like the following, if you do, you will need to open up the files tagged with CONFLICT and resolve the merge conflicts. Once that's done, you will need to commit the changes and push the commit (e.g., git push) back to Github.\n",
    "\n",
    "```\n",
    "git merge main\n",
    "Auto-merging stumpy/aamp_stimp.py\n",
    "Auto-merging stumpy/core.py\n",
    "Auto-merging stumpy/mpdist.py\n",
    "CONFLICT (content): Merge conflict in stumpy/mpdist.py\n",
    "Auto-merging stumpy/mstumped.py\n",
    "CONFLICT (content): Merge conflict in stumpy/mstumped.py\n",
    "Auto-merging stumpy/ostinato.py\n",
    "Auto-merging stumpy/stimp.py\n",
    "CONFLICT (content): Merge conflict in stumpy/stimp.py\n",
    "Auto-merging stumpy/stumped.py\n",
    "CONFLICT (content): Merge conflict in stumpy/stumped.py\n",
    "Automatic merge failed; fix conflicts and then commit the result.\n",
    "You will need to open up the files tagged with CONFLICT and resolve the merge conflicts. Once that's done, you will need to commit the changes and push the commit (e.g., git push) back to Github.\n",
    "```\n",
    ":::"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Create a Pull Request\n",
    "\n",
    "Now, your updated code is on GitHub in your fork of STUMPY. If you want the STUMPY maintainers to see it, you need to create a `Pull Request`.  There are instructions [here](https://docs.github.com/en/desktop/contributing-and-collaborating-using-github-desktop/creating-an-issue-or-pull-request#creating-a-pull-request), but GitHub is also pretty smart. If you navigate to your fork of the repository shortly after you push a commit, you'll often see a message like \"Your recently pushed branches: X  <Compare & Pull Request>\". Clicking that will automatically create your pull request.  Like a commit, make sure to give it a descriptive name. If your change isn't quite working yet, then you can preface your pull request with `[WIP]` which stands for \"Work in Progress.\" In the body of your Pull Request, reference the Issue Number that you're working on. GitHub will automatically link your pull request to that issue. This just makes housekeeping and cross referencing a lot easier.\n",
    "\n",
    "Here's your next chance to communicate with the maintainers. Let them know what changes you made and if you need any help. This pull request will now be the running dialogue between you and the maintainers as you work on the issue.\n",
    "\n",
    "Continuous integration systems automatically determine the suitability of merging pull requests. They check the formatting, test coverage, and test success of your code. After you submit a pull request, you'll see these running (as comments in your pull request). If they fail, your code will not be merged until the failure is fixed. In STUMPY, locally passing `flake8`, `black`, and `./setup.sh dev && ./test.sh` should ensure your continuous integration tests pass.\n",
    "\n",
    "Checklist:  \n",
    "- [ ] Create a Pull Request  \n",
    "- [ ] Write an informative Pull Request Message  \n",
    "- [ ] Monitor your Pull Request for continuous integration checks and messages from the maintainers"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Work on your Pull Request (PR)\n",
    "\n",
    "It is extremely likely that the maintainer will have questions, comments, or suggestions on your PR. This is an opportunity for collaboration and should benefit both parties. Also, it is useful to know that you do __not__ need to create a new branch __if__ you are going to work on the same issue for which you've already submitted a PR. Instead, based on the maintainers' feedback, continue refining your contribution using the same branch that you had used before. Now, every commit that you make __and push__ will automatically be reflected in the existing pull request. To recap, if you already have an existing open PR, then after you make any changes in your local code just `commit` and `push` to your fork like before and these changes will automatically show up in the corresponding PR. \n",
    "\n",
    "> Warning: After every change, make sure to run your formatting checks and unit tests.\n",
    "\n",
    "Checklist:  \n",
    "- [ ] Be open minded, responsive, and polite"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Merge!\n",
    "\n",
    "When the contribution is nice and polished, the maintainers will `merge` it into STUMPY.  **Success!**\n",
    "\n",
    "Checklist:  \n",
    "- [ ] Celebrate  \n",
    "- [ ] Go find another issue"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## What to do when it goes wrong\n",
    "\n",
    "Invariably, something goes wrong. Remember, you're not in this alone. The open source community is a *community* and we appreciate your interest and contribution to STUMPY. If your barrier is related to an issue already filed in GitHub, that issue probably a great place to request additional information and help. If your barrier is related to your solution to an issue, go ahead and submit your progress as a pull request. As always, be polite and be patient."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2020-09-25T11:16:34.200791Z",
     "iopub.status.busy": "2020-09-25T11:16:34.200791Z",
     "iopub.status.idle": "2020-09-25T11:16:34.210791Z",
     "shell.execute_reply": "2020-09-25T11:16:34.210791Z",
     "shell.execute_reply.started": "2020-09-25T11:16:34.200791Z"
    }
   },
   "source": [
    "## Final Checklist:\n",
    "- [ ] Create GitHub account  \n",
    "- [ ] Install Git  \n",
    "- [ ] Identify an issue  \n",
    "- [ ] Read CONTRIBUTING.md  \n",
    "- [ ] Post your proposal in the issue  \n",
    "- [ ] Fork STUMPY to your own account  \n",
    "- [ ] Clone a local copy  \n",
    "- [ ] Create a branch for your work  \n",
    "- [ ] Create a virtual environment  \n",
    "- [ ] Install dependencies  \n",
    "- [ ] Run the unit tests  \n",
    "- [ ] Write/update any unit tests  \n",
    "- [ ] Run `black --exclude=\".*\\.ipynb\" --extend-exclude=\".venv\" --diff ./` to reformat any python files you changed  \n",
    "- [ ] Run `flake8 --extend-exclude=.venv ./` to identify any formatting errors before you submit your `pull request`  \n",
    "- [ ] Run the unit tests. In STUMPY, you'll run `./setup.sh dev && ./test.sh`  \n",
    "- [ ] `git add your_file`  \n",
    "- [ ] `git commit -m 'Great Commit Message'`  \n",
    "- [ ] `git push`  \n",
    "- [ ] Create a Pull Request  \n",
    "- [ ] Write an informative Pull Request Message  \n",
    "- [ ] Monitor your Pull Request for continuous integration checks and messages from the maintainers  \n",
    "- [ ] Be open minded, responsive, and polite  \n",
    "- [ ] Celebrate  \n",
    "- [ ] Go find another issue  "
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.12.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
